#include "FreeRTOS.h"
#include "task.h"
#include "FreeRTOSConfig.h"
#include "STC32G.h"
#include "stdio.h"


/*
目前移植的FreeRTOS版本支持STC32G的larg-ROM和huge-ROM两个版本

切换larg-ROM的配置方法：
1. FreeRTOSConfig.h 里面配置configUSE_ROMHUGE 为 0
2. 点击Keil工程配置按钮【Options for Target】-> 【Target】-> 【Code Rom Size】-> Larg模式
3. 点击Keil工程配置按钮【Options for Target】-> 【Target】-> 【C251】 -> 【Define】 输入 configSUPPORT_MCS251
4. 点击Keil工程配置按钮【Options for Target】-> 【Target】-> 【C251】 -> 【Level】 选择4级
5. 点击Keil工程配置按钮【Options for Target】-> 【Target】-> 【C251】 勾选 Link Code
6. 点击Keil工程配置按钮【Options for Target】-> 【Target】-> 【C251】 勾选 Generate reentrant


切换Huge-ROM的配置方式:
1. FreeRTOSConfig.h 里面配置configUSE_ROMHUGE 为 1
2. 点击Keil工程配置按钮【Options for Target】-> 【Target】-> 【Code Rom Size】-> Huge模式
3. 点击Keil工程配置按钮【Options for Target】-> 【Target】-> 【Exeternal Memory】-> 【ROM】 起始地址：0xFE2000 大小：0x1E000
4. 点击Keil工程配置按钮【Options for Target】-> 【Target】-> 【C251】 -> 【Define】 输入 configSUPPORT_MCS251
5. 点击Keil工程配置按钮【Options for Target】-> 【Target】-> 【C251】 -> 【Level】 选择4级
6. 点击Keil工程配置按钮【Options for Target】-> 【Target】-> 【C251】 勾选 Link Code
7. 点击Keil工程配置按钮【Options for Target】-> 【Target】-> 【C251】 勾选 Generate reentrant


port.c 为移植接口，注释用英文撰写，为了保持字体编码兼容。
为了方便阅读和学习，以C语言编写为主，但这不是最优方案，还可以使用汇编进行优化。
当前方案，在35M速度下：
任务切换速度耗时在10us左右，使用汇编优化，可以到5~8us左右。

默认系统时钟24M，可以根据需要，自己调整。

如果要启动软件仿真，需要进行如下操作：

点击Keil工程配置按钮【Options for Target】-> 【Target】-> 【C251】 -> 【Define】 输入 __SOFT_DEBUG__ （注意不要删除configSUPPORT_MCS251）

开启软件仿真以后，不能在真实硬件上跑。

*/

#define LED0_TASK_PRIO  2

#define LED0_STK_SIZE   128  

#define LED1_TASK_PRIO  1

#define LED1_STK_SIZE   128 

TaskHandle_t LED0Task_Handler;

TaskHandle_t LED1Task_Handler;

void led0_task(void *pvParameters);

void led1_task(void *pvParameters);


void Delay1000ms()  //@24.000MHz
{
    unsigned char i, j, k;

    i = 92;
    j = 50;
    k = 238;
    do
    {
        do
        {
            while (--k);
        } while (--j);
    } while (--i);
}


void UartInit(void)		//115200bps@24.000MHz
{
    SCON = 0x50;
    AUXR |= 0x40;
    AUXR &= 0xFE;
    TMOD &= 0x0F;
    TL1 = 0xCC;
    TH1 = 0xFF;
    ET1 = 0;
    TR1 = 1;
}

//UART1 
void UART1_SendData(uint8_t dat)
{
    SBUF=dat;
    while(TI!=1);
    TI=0;
}

void UART1_SendString(uint8_t *str)
{
    while(*str)
    {
        UART1_SendData(*str++);
    }
}

void main(void)
{
    uint8_t i = 2, j = 3;
    WTST = 0; 

    P0M1 = 0x00;   P0M0 = 0x00;
    P1M1 = 0x00;   P1M0 = 0x00;
    P2M1 = 0x00;   P2M0 = 0x00;
    P3M1 = 0x00;   P3M0 = 0x00;
    P4M1 = 0x00;   P4M0 = 0x00;
    P5M1 = 0x00;   P5M0 = 0x00;
    P6M1 = 0x00;   P6M0 = 0x00;
    P7M1 = 0x00;   P7M0 = 0x00;
    
    P40 = 0;
    
    UartInit();
    UART1_SendData(0xa);

    xTaskCreate((TaskFunction_t )led0_task,
                (const char*    )"led0_task",
                (uint16_t       )LED0_STK_SIZE,
                (void*          )&i,
                (UBaseType_t    )LED0_TASK_PRIO,
                (TaskHandle_t*  )&LED0Task_Handler);
 
    xTaskCreate((TaskFunction_t )led1_task,
                (const char*    )"led1_task",
                (uint16_t       )LED1_STK_SIZE,
                (void*          )&j,
                (UBaseType_t    )LED1_TASK_PRIO,
                (TaskHandle_t*  )&LED1Task_Handler);
    vTaskStartScheduler();

}



void led0_task(void *pvParameters)
{
    uint8_t a = *(uint8_t *)pvParameters;
    while(1)
    {
        P0=~P0;
        P60 = !P60;
        UART1_SendData(a);
        //UART1_SendString("led0_task is running!\r\n");
        vTaskDelay(500);
    }
}   

void led1_task(void *pvParameters)
{
    uint8_t a = *(uint8_t *)pvParameters;
    while(1)
    {
        P1 = ~P1;
        P61 = !P61;
        UART1_SendData(a);
         //UART1_SendString("led1_task is running!\r\n");
        vTaskDelay(1000);
    }
}

